package com.qing.utils.lottery.dlt;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * @author guoqf
 */
public class DltCalUtil {
    private static int[] winNumbers = {4, 5, 6, 26, 27, 7, 12};


    private static int[][] boughtNumbersArray = {
            {4, 12, 16, 20, 26, 4, 6},
            {10, 12, 25, 26, 34, 7, 8},
            {10, 17, 18, 22, 23,4 , 7},
            {3, 5, 19, 20, 32, 3, 5},
            {1, 6, 12, 13, 17, 6, 12}

            /*,

            {4, 5, 10, 20, 22, 7, 8},
            {5, 7, 10, 20, 22, 4, 8},
            {5, 8, 10, 20, 22, 4, 7},
            {5, 10, 20, 22, 28, 8, 11},
            {5, 10, 20, 22, 32, 7, 12},
            {9, 10, 17, 20, 30, 4, 11},
            {3, 9, 22, 29, 31, 1, 9},
            {2, 19, 25, 30, 34, 10, 12},
            {14, 20, 21, 23, 32, 3, 5},
            {11, 20, 22, 24, 33, 6, 7}*/
    };


    public static void main(String[] args) {

        match(winNumbers, boughtNumbersArray);

    }


    private static List<WinningCondition> winningMap = new ArrayList<>(16);


    static {
        winningMap.add(new WinningCondition(5, 2, 1, -1, "一等奖"));
        winningMap.add(new WinningCondition(5, 1, 2, -1, "二等奖"));
        winningMap.add(new WinningCondition(5, 0, 3, 10000, "三等奖"));
        winningMap.add(new WinningCondition(4, 2, 4, 3000, "四等奖"));
        winningMap.add(new WinningCondition(4, 1, 5, 300, "五等奖"));
        winningMap.add(new WinningCondition(3, 2, 6, 200, "六等奖"));
        winningMap.add(new WinningCondition(4, 0, 7, 100, "七等奖"));
        winningMap.add(new WinningCondition(3, 1, 8, 15, "八等奖"));
        winningMap.add(new WinningCondition(2, 2, 8, 15, "八等奖"));
        winningMap.add(new WinningCondition(3, 0, 9, 5, "九等奖"));
        winningMap.add(new WinningCondition(2, 1, 9, 5, "九等奖"));
        winningMap.add(new WinningCondition(1, 2, 9, 5, "九等奖"));
        winningMap.add(new WinningCondition(0, 2, 9, 5, "九等奖"));

    }
    /*
    本期开奖号码:
2 14 19 21 25 28 11
购买号码:
7 14 18 20 23 24 4, 2 4 15 16 28 29 8, 7 8 12 13 14 22 3, 2 10 14 17 18 29 3, 5 13 21 22 26 30 16
     */


    private static void match(int[] bigWinningNumbers, int[][] boughtNumbers) {
        System.out.println("本期开奖号码是：" + Arrays.toString(bigWinningNumbers));
        DltNumbers winningNumbers = parseLotteryNumbers(bigWinningNumbers);

        List<DltNumbers> bNumbers = new ArrayList<>(boughtNumbers.length);
        for (int[] s : boughtNumbers) {
            bNumbers.add(parseLotteryNumbers(s));
        }

        List<WinningMatchResult> rList = new ArrayList<>(bNumbers.size());

        for (DltNumbers bNumber : bNumbers) {
            NumbersMatchResult matchResult = bNumber.match(winningNumbers);
            WinningMatchResult winningMatchResult = matchResult.matchWinning(winningMap);
            rList.add(winningMatchResult);
        }
        rList.sort(Comparator.comparingInt(WinningMatchResult::getPrizeClass));
        System.out.println("本期购买号码是：");

        rList.forEach(r -> {
            NumbersMatchResult numbersMatchResult = r.getNumbersMatchResult();
            DltNumbers dltNumbers = numbersMatchResult.getDltNumbers();
            DltNumbers winNumbers = numbersMatchResult.getWinNumbers();
            System.out.printf("购买号码：[红(%s), 蓝(%s)]， 奖级：[%s]，金额：[%s]，中奖号码：[红(%s), 蓝(%s)]", Arrays.toString(dltNumbers.getRedNumbers()), Arrays.toString(dltNumbers.getBlueNumbers()), r.getPrizeClassDesc(), r.getBonus(), Arrays.toString(winNumbers.getRedNumbers()), Arrays.toString(winNumbers.getBlueNumbers())).println();
        });
    }


    private static DltNumbers parseLotteryNumbers(int[] wNumbers) {
        // 6红+1蓝

        int[] redNumbers = new int[5];
        System.arraycopy(wNumbers, 0, redNumbers, 0, wNumbers.length - 2);
        int[] blueNumbers = new int[2];
        System.arraycopy(wNumbers, 5, blueNumbers, 0, 2);
        Arrays.sort(redNumbers);
        return new DltNumbers(redNumbers, blueNumbers);
    }


    @Data
    @AllArgsConstructor
    private static class WinningCondition {

        private int redCount;

        private int blueCount;

        private int prizeClass;


        private int bonus;

        private String prizeClassDesc;


    }


    @Data
    @AllArgsConstructor
    private static class WinningMatchResult {

        private boolean wined;

        private NumbersMatchResult numbersMatchResult;

        private int prizeClass;

        private String prizeClassDesc;

        private int bonus;

    }

    @Data
    @AllArgsConstructor
    private static class NumbersMatchResult {

        private int redCount;

        private int blueCount;


        private DltNumbers dltNumbers;

        private DltNumbers winNumbers;


        public WinningMatchResult matchWinning(List<WinningCondition> conditions) {
            for (WinningCondition condition : conditions) {
                boolean matched = matchOne(condition);
                if (matched) {
                    return new WinningMatchResult(true, this, condition.getPrizeClass(), condition.getPrizeClassDesc(), condition.getBonus());
                }
            }
            return new WinningMatchResult(false, this, 100, "未中奖", 0);
        }

        public boolean matchOne(WinningCondition condition) {
            return condition.getRedCount() == this.redCount && condition.getBlueCount() == this.blueCount;
        }

    }

    @Data
    @AllArgsConstructor
    private static class DltNumbers {

        private int[] redNumbers;

        private int[] blueNumbers;

        public NumbersMatchResult match(DltNumbers dltNumbers) {
            int[] mRedNumbers = dltNumbers.getRedNumbers();
            int[] mBlueNumbers = dltNumbers.getBlueNumbers();
            int[] winRedNumbers = new int[mRedNumbers.length];
            int[] winBlueNumbers = new int[mBlueNumbers.length];
            int redCount = 0;
            int blueCount = 0;

            for (int i = 0, j = 0; i < blueNumbers.length && j < mBlueNumbers.length; ) {


                int rNumber = blueNumbers[i];
                int mRedNumber = mBlueNumbers[j];
                if (rNumber == mRedNumber) {
                    winBlueNumbers[blueCount++] = rNumber;
                    i++;
                    j++;
                    continue;
                }

                if (rNumber < mRedNumber) {
                    i++;
                    continue;
                }

                j++;
            }

            for (int i = 0, j = 0; i < redNumbers.length && j < mRedNumbers.length; ) {


                int rNumber = redNumbers[i];
                int mRedNumber = mRedNumbers[j];
                if (rNumber == mRedNumber) {
                    winRedNumbers[redCount++] = rNumber;
                    i++;
                    j++;
                    continue;
                }

                if (rNumber < mRedNumber) {
                    i++;
                    continue;
                }

                j++;
            }

            int[] init = new int[6];
            winRedNumbers = ArrayUtils.removeElements(winRedNumbers, init);
            winBlueNumbers = ArrayUtils.removeElements(winBlueNumbers, init);

            return new NumbersMatchResult(redCount, blueCount, this, new DltNumbers(winRedNumbers, winBlueNumbers));
        }

    }

}
